package bhz.netty_me.return_func;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.io.UnsupportedEncodingException;

/*
* 第一个TCP服务器
* */
public class TcpServer {

 public static void main(String[] args) throws InterruptedException {
   EventLoopGroup bossGroup = new NioEventLoopGroup();
   EventLoopGroup workerGroup = new NioEventLoopGroup();
   try {
     ServerBootstrap b = new ServerBootstrap();
     b.group(bossGroup, workerGroup)
         .channel(NioServerSocketChannel.class)
         .childHandler(new ChannelInitializer<SocketChannel>() {
           @Override
           public void initChannel(SocketChannel ch)
               throws Exception {
             ch.pipeline().addLast(new TcpServerHandler());
           }
         });
     ChannelFuture f = b.bind(8080).sync();
     f.channel().closeFuture().sync();
   } finally {
     workerGroup.shutdownGracefully();
     bossGroup.shutdownGracefully();
   }
 }

}

class TcpServerHandler extends ChannelHandlerAdapter {

 // 接收到新的数据
 @Override
 public void channelRead(final ChannelHandlerContext ctx, Object msg)
         throws UnsupportedEncodingException {

     // 读操作省略...

     // 发送数据到客户端
     ChannelFuture future = ctx.writeAndFlush("message"); // 返回值类型为ChannelFuture
     future.addListener(new ChannelFutureListener() {

         // write操作完成后调用的回调函数
         @Override
         public void operationComplete(ChannelFuture future) throws Exception {
             if(future.isSuccess()) { // 是否成功
                 System.out.println("write操作成功");
             } else {
                 System.out.println("write操作失败");
             }
             ctx.close(); // 如果需要在write后关闭连接，close应该写在operationComplete中。注意close方法的返回值也是ChannelFuture
         }
     });

 }

 @Override
 public void channelActive(ChannelHandlerContext ctx) {
   System.out.println("客户端进入...");
 }

 @Override
 public void channelInactive(ChannelHandlerContext ctx){
   System.out.println("客户端退出...");
 }

 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
   cause.printStackTrace();
   ctx.close();
 }
}